<template>
    <el-upload
        :file-list="fileList"
        @update:file-list="updateFileList"
        :multiple="true"
        :drag="true"
        :accept="accept"
        :show-file-list="showFileList"
        :list-type="'text'"
        :auto-upload="true"
        :limit="limit"
        :on-preview="preview"
        :on-remove="remove"
        :on-success="success"
        :on-error="error"
        :on-progress="progress"
        :on-change="change"
        :on-exceed="exceed"
        :before-upload="beforeUpload"
        :before-remove="beforeRemove"
        :http-request="httpRequest"
    >
        <slot>
            <el-icon class="el-icon--upload">
                <upload-filled/>
            </el-icon>
            <div class="el-upload__text">
                拖动文件到这里或<em>点击上传</em>
            </div>
        </slot>
        <template #tip>
            <slot name="tip">
                <div class="el-upload__tip">
                    上传过程中无法取消
                </div>
            </slot>
        </template>
        <template #file="{file}">
            <slot name="file" :file="file">
            </slot>
        </template>
    </el-upload>
</template>

<script setup lang="ts">
import {ref} from "vue";
import {UploadRequestOptions, UploadUserFile} from "element-plus";
import {UploadFilled} from "@element-plus/icons-vue";
import {fileApi} from "/@/api/file";

interface Props {
    modelValue?: any
    accept?: string;
    limit?: number;
    showFileList?: boolean;//是否显示上传的文件列表
    preview?: Function;//点击文件列表中已上传的文件时的钩子，用于预览
    remove?: Function;//文件列表移除文件时的钩子
    success?: Function;//文件上传成功时的钩子
    error?: Function;  //文件上传失败时的钩子
    progress?: Function;  //文件上传时的钩子
    change?: Function;  //文件状态改变时的钩子，添加文件、上传成功和上传失败时都会被调用
    exceed?: Function;//当超出限制时，执行的钩子函数
    beforeUpload?: Function;//上传文件之前的钩子，参数为上传的文件， 若返回false或者返回 Promise 且被 reject，则停止上传
    beforeRemove?: Function;//删除文件之前的钩子，参数为上传的文件和文件列表， 若返回 false 或者返回 Promise 且被 reject，则停止删除。
}

const emit = defineEmits([
    'update:modelValue',
])
const props = withDefaults(defineProps<Props>(), {
    modelValue: () => [],
    showFileList: true
});
const fileList = ref<UploadUserFile[]>(props.modelValue)
//根据Promise状态确定上传成功或失败
const httpRequest = (options: UploadRequestOptions): XMLHttpRequest | Promise<unknown> => {
    return fileApi.uploadFile({
        storageId: undefined,
        file: options.file
    }, options.onProgress);
};
const updateFileList = (files: UploadUserFile[]) => {
    fileList.value = files;
    emit('update:modelValue', files)
}
</script>
<style scoped lang="scss">

</style>
